package com.runa.rccprotocol.dto.guangda;

import com.alibaba.fastjson.JSON;
import com.runa.monitor.comm.dto.Node;
import com.runa.persistence.DateUtil;
import com.runa.protocol.enums.ByteOrder;
import com.runa.protocol.util.ByteUtil;
import com.runa.rccprotocol.dto.ConcentratorRequestData;
import lombok.Getter;

import java.util.ArrayList;
import java.util.List;

/**
 * 2024/7/12 14:18
 * zhangYB
 */
public class GdRequestData extends ConcentratorRequestData {

    private static final byte startSymbol = 0x68;

    private byte control = 0x1C;

    private Integer equIndex;

    private Integer equNum;

    private byte[] requestData;

    private Integer clientId = 0;

    @Getter
    private List<Node> nodes;

    private String equNo;

    private Long readTime = DateUtil.timestamp();

    public GdRequestData(String address, String equNo) {
        super(address);
        this.equNo = equNo;
        setHaveResult(true);
    }

    public GdRequestData(String address, String equNo, Integer clientId) {
        super(address);
        this.equNo = equNo;
        this.clientId = clientId;
        setHaveResult(true);
    }

    public GdRequestData(String address, Integer equIndex, Integer equNum, Integer clientId) {
        super(address);
        this.equIndex = equIndex;
        this.equNum = equNum;
        this.clientId = clientId;
        setHaveResult(true);
    }

    public void addNode(Node node) {
        if (null == this.nodes) {
            this.nodes = new ArrayList<>();
        }
        this.nodes.add(node);
    }

    public void setNodes(List<Node> nodes) {
        this.nodes = nodes;
    }

    @Override
    public byte[] getData() {
        return requestData;
    }

    public void valveOpen(Integer opening) {
        byte open = opening == null ? (byte)0x99 : opening == 0 ? (byte)0x99 : (byte)0x55;
    }


    public static void main(String[] args) {
        GdRequestData gdRequestData = new GdRequestData("000119020018", "0190405141");
        gdRequestData.valveOpen(true, (byte)0, (byte)2);
        System.out.println(ByteUtil.byteToHexString(gdRequestData.getData()));

//        byte[] bytes = ByteUtil.hexStringToByteFlip("22017091075");
//        System.out.println(ByteUtil.byteToHexString(bytes));
//
//        GdRequestData requestData = new GdRequestData("000117090069", "22017091075", 1);
//        requestData.read();
//        System.out.println(ByteUtil.byteToHexString(requestData.getData()));

    }

    public void valveOpen(Boolean open, byte sign, byte port) {
        byte[] bytes = new byte[100];
        int index = 0;
        bytes[index++] = (byte)0x68;
        byte[] addressBytes = ByteUtil.hexStringToByteFlip(address);
        System.arraycopy(addressBytes, 0, bytes, index, addressBytes.length);
        index += 11;
        bytes[index++] = startSymbol;
        bytes[index++] = 0x08;

        byte[] valveOpen188Bytes = valveOpen188(open);
        int len = valveOpen188Bytes.length + 2;
        bytes[index++] = (byte)(len & 0xff);
        bytes[index++] = (byte)(len >> 8 & 0xff);
        bytes[index++] = (byte)((sign + 0x33) & 0xff);
        bytes[index++] = (byte)((port + 0x33) & 0xff);

        for (byte b : valveOpen188Bytes) {
            bytes[index++] = (byte)((b + 0x33) & 0xff);
        }
        bytes[index++] = ByteUtil.sum(bytes, 0, index);
        bytes[index++] = 0x16;

        requestData = new byte[index];
        System.arraycopy(bytes, 0, requestData, 0, index);
        setHaveResult(true);
    }

    public byte[] valveOpen188(Boolean open) {
        byte[] bytes = new byte[100];
        int index = 0;
        bytes[index++] = (byte)0x68;
        bytes[index++] = (byte)0x20;

        if (equNo.length() % 2 == 1) {
            equNo = "0" + equNo;
        }
        byte[] equNoBytes = ByteUtil.hexStringToByteFlip(equNo);
        System.arraycopy(equNoBytes, 0, bytes, index, equNoBytes.length);
        index += 7;

        bytes[index++] = (byte)0x04;
        bytes[index++] = (byte)0x04;

        bytes[index++] = (byte)(((byte)0xA0 + (byte)0x33) & 0xff);
        bytes[index++] = (byte)(((byte)0x17 + (byte)0x33) & 0xff);
        bytes[index++] = (byte)(((byte)0x01 + (byte)0x33) & 0xff);
        bytes[index++] = open ? (byte)((0x55 + 0x33) & 0xff) : (byte)((0x99 + 0x33) & 0xff);

        bytes[index++] = ByteUtil.sum(bytes, 0, index);
        bytes[index++] = (byte)0x16;
        byte[] r = new byte[index];
        System.arraycopy(bytes, 0, r, 0, index);
        return r;
    }



    public byte[] requestDataByNo() {
        requestData = new byte[25];

        int index = 0;
        requestData[index++] = startSymbol;
        byte[] addressBytes = ByteUtil.hexStringToByte(address);
        for (int i = addressBytes.length-1; i >= 0; i--) {
            requestData[index++] = addressBytes[i];
        }
        ByteUtil.intToBcd(requestData, index, clientId, true);
        index += 5;
        requestData[index++] = startSymbol;
        requestData[index++] = control;
        requestData[index++] = 0x07;
        requestData[index++] = 0x00;

        if (equNo.length() % 2 == 1) {
            equNo = "0" + equNo;
        }

        byte[] equNoBytes = ByteUtil.hexStringToBytesFlip(equNo);
        for (int i = 0; i < 7; i++) {
            if (i < equNoBytes.length) {
                requestData[index++] = (byte)((equNoBytes[i] + 0x33) & 0xff);
            } else {
                requestData[index++] = 0x33;
            }
        }

        requestData[index++] = ByteUtil.sum(requestData, 0, index);

        requestData[index] = 0x16;

        return requestData;
    }


    public byte[] requestDataByIndex() {
        requestData = new byte[24];

        int index = 0;
        requestData[index++] = startSymbol;
        byte[] addressBytes = ByteUtil.hexStringToByte(address);
        for (int i = addressBytes.length-1; i >= 0; i--) {
            requestData[index++] = addressBytes[i];
        }
        ByteUtil.intToBcd(requestData, index, clientId, true);

        index += 5;
        requestData[index++] = startSymbol;
        requestData[index++] = 0x1B;
        requestData[index++] = 0x06;
        requestData[index++] = 0x00;
        requestData[index++] = 0x33;
        requestData[index++] = 0x33;

        requestData[index++] = 0x33;
        requestData[index++] = (byte)((equIndex + 0x33) & 0xff);
        requestData[index++] = 0x33;
        requestData[index++] = (byte)((equNum + 0x33) & 0xff);

        requestData[index++] = ByteUtil.sum(requestData, 0, index);

        requestData[index] = 0x16;

        return requestData;
    }


    public String getMessage() {
        byte[] data = getData();
        return ByteUtil.byteToHexString(data);
    }


    public Integer getEquIndex() {
        return equIndex;
    }

    public void setEquIndex(Integer equIndex) {
        this.equIndex = equIndex;
    }

    public Integer getEquNum() {
        return equNum;
    }

    public void setEquNum(Integer equNum) {
        this.equNum = equNum;
    }

    public Long getReadTime() {
        return readTime;
    }

    public void setReadTime(Long readTime) {
        this.readTime = readTime;
    }

    public Integer getClientId() {
        return clientId;
    }

    public void setClientId(Integer clientId) {
        this.clientId = clientId;
    }

    @Override
    public String toString() {
        try {
            return JSON.toJSONString(this);
        } catch (Exception e) {
            return String.format("解析JSON失败, %s", e);
        }
    }
}
